﻿using GTM = Gadgeteer.Modules;

namespace Gadgeteer.Modules.GHIElectronics
{
    /// <summary>
    /// A EBlockExpansion module for Microsoft .NET Gadgeteer
    /// </summary>
    /// /// <example>
    /// <para>The following example uses a <see cref="EBlockExpansion"/> object to use existing EBlock modules. 
    /// Since this module's usage can vary greatly depending on the EBlock used, visit http://wiki.tinyclr.com/index.php?title=Eblock_Expansion_Module for more information.
    /// </para>
    /// </example>
    public class EBlockExpansion : GTM.Module
    {
        // -- CHANGE FOR MICRO FRAMEWORK 4.2 --
        // If you want to use Serial, SPI, or DaisyLink (which includes GTI.SoftwareI2C), you must do a few more steps
        // since these have been moved to separate assemblies for NETMF 4.2 (to reduce the minimum memory footprint of Gadgeteer)
        // 1) add a reference to the assembly (named Gadgeteer.[interfacename])
        // 2) in GadgeteerHardware.xml, uncomment the lines under <Assemblies> so that end user apps using this module also add a reference.
        private Socket eBlockExpansionSocket;

        // Note: A constructor summary is auto-generated by the doc builder.
        /// <summary></summary>
        /// <param name="socketNumber">The socket that this module is plugged in to.</param>
        public EBlockExpansion(int socketNumber)
        {
            eBlockExpansionSocket = Socket.GetSocket(socketNumber, true, this, null);
        }

        /// <summary>
        /// The mainboard socket number which this EBlockExpansion module is plugged into.
        /// </summary>
        public int EBlockExpansionSocketNumber { get { return eBlockExpansionSocket.SocketNumber; } }

        /// <summary>
        /// Returns a digital input interface associated with the specified pin on this module.
        /// </summary>
        /// <param name="pin">The pin to assign to the interface.</param>
        /// <param name="glitchFilterMode">
        ///  A value from the <see cref="T:Microsoft.Gadgeteer.Interfaces.GlitchFilterMode"/> enumeration that specifies 
        ///  whether to enable the glitch filter on this interface.
        /// </param>
        /// <param name="resistorMode">The resistor mode for the interface port.</param>
        /// <returns>The interface.</returns>
        /// <exception cref="System.Exception">
        ///  The specified pin has already been reserved on this module.
        /// </exception>
        public Interfaces.DigitalInput SetupDigitalInput(Socket.Pin pin, Interfaces.GlitchFilterMode glitchFilterMode, Interfaces.ResistorMode resistorMode)
        {
            return new Interfaces.DigitalInput(eBlockExpansionSocket, pin, glitchFilterMode, resistorMode, this);
        }

        /// <summary>
        /// Returns a digital output interface associated with the specified pin on this module.
        /// </summary>
        /// <param name="pin">The pin to assign to the interface.</param>
        /// <param name="initialState">The initial state to place on the interface output port.</param>
        /// <returns>The interface.</returns>
        /// <exception cref="System.Exception">
        ///  The specified pin has already been reserved on this module.
        /// </exception>
        public Interfaces.DigitalOutput SetupDigitalOutput(Socket.Pin pin, bool initialState)
        {
            return new Interfaces.DigitalOutput(eBlockExpansionSocket, pin, initialState, this);
        }

        /// <summary>
        /// Returns a digital input/output interface associated with the specified pin on this module.
        /// </summary>
        /// <param name="pin">The pin to assign to the interface.</param>
        /// <param name="initialState">
        ///  The initial state to place on the interface port; 
        ///  this value becomes effective as soon as the port is enabled as an output port.
        /// </param>
        /// <param name="glitchFilterMode">
        ///  A value from the <see cref="T:Microsoft.Gadgeteer.Interfaces.GlitchFilterMode"/> enumeration that specifies 
        ///  whether to enable the glitch filter on this interface.
        /// </param>
        /// <param name="resistorMode">The resistor mode for the interface port.</param>
        /// <returns>The interface.</returns>
        /// <exception cref="System.Exception">
        ///  The specified pin has already been reserved on this module.
        /// </exception>
        public Interfaces.DigitalIO SetupDigitalIO(Socket.Pin pin, bool initialState, Interfaces.GlitchFilterMode glitchFilterMode, Interfaces.ResistorMode resistorMode)
        {
            return new Interfaces.DigitalIO(eBlockExpansionSocket, pin, initialState, glitchFilterMode, resistorMode, this);
        }

        /// <summary>
        /// Returns an interrupt input interface associated with the specified pin on this module.
        /// </summary>
        /// <param name="pin">The pin to assign to the interface.</param>
        /// <param name="glitchFilterMode">
        ///  A value from the <see cref="T:Microsoft.Gadgeteer.Interfaces.GlitchFilterMode"/> enumeration that specifies 
        ///  whether to enable the glitch filter on this interface.
        /// </param>
        /// <param name="resistorMode">The resistor mode for the interface port.</param>
        /// <param name="interruptMode">The interrupt mode for the interface port.</param>
        /// <returns>The interface</returns>
        /// <exception cref="System.Exception">
        ///  The specified pin has already been reserved on this module.
        /// </exception>
        public Interfaces.InterruptInput SetupInterruptInput(Socket.Pin pin, Interfaces.GlitchFilterMode glitchFilterMode, Interfaces.ResistorMode resistorMode, Interfaces.InterruptMode interruptMode)
        {
            return new Interfaces.InterruptInput(eBlockExpansionSocket, pin, glitchFilterMode, resistorMode, interruptMode, this);
        }

        /// <summary>
        /// Returns an analog input interface associated with the specified pin on this module.
        /// </summary>
        /// <param name="pin">The pin to assign to the interface.</param>
        /// <returns>The interface.</returns>
        public Interfaces.AnalogInput SetupAnalogInput(Socket.Pin pin)
        {
            return new Interfaces.AnalogInput(eBlockExpansionSocket, pin, this);
        }

        // TODO:  Determine whether AnalogOutput should be added to Gadgeteer.Interfaces


        /// <summary>
        /// Returns an analog output interface associated with the specified pin on this module.
        /// </summary>
        /// <param name="pin">The pin to assign to the interface.</param>
        /// <returns>The interface.</returns>
        public Interfaces.AnalogOutput SetupAnalogOutput(Socket.Pin pin)
        {
            return new Interfaces.AnalogOutput(eBlockExpansionSocket, pin, this);
        }

        /// <summary>
        ///  Returns an pulse width modulation (PWM) output interface associated with the specified pin on this module.
        /// </summary>
        /// <param name="pin">The pin to use for the PWM interface.</param>
        /// <returns>The PWM interface.</returns>
        public Interfaces.PWMOutput SetupPWMOutput(Socket.Pin pin)
        {
            return new Interfaces.PWMOutput(eBlockExpansionSocket, pin, false, this);
        }
    }
}
